package common;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Calendar;
import java.util.Date;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import org.hibernate.SessionFactory;
import business.services.IServicioCanchas;
import business.services.IServicioClases;
import business.services.IServicioClientes;
import business.services.IServicioReservas;
import business.services.IServicioUsuarios;
import business.services.ServiceException;
import business.services.ServicioCanchas;
import business.services.ServicioClases;
import business.services.ServicioClientes;
import business.services.ServicioReservas;
import business.services.ServicioUsuarios;
import data.entities.TipoPago;
import data.repository.HibernateUtil;
import data.repository.IRepository;
import data.repository.QueryParameter;
import data.repository.Repository;
import data.repository.RepositoryException;

public class Contexto {
	public static final Double PrecioPorMembresia = 50.0;
	
	public static final Double PrecioPorClase = 100.0;
	
	public static final Double PrecioPorReserva = 150.0;
	
	public static Integer cupoMaximoPorClase = 2;
	
	public static void inicializarModeloDatos() {
		@SuppressWarnings("unused")
		SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
		
		System.out.println("Session Factory inicializada");	
	}
	
	public static void inicializarContextoDemo() {
		inicializarModeloDatos();
		generarUsuarios();
		generarTiposPago();
		generarCanchas();
		generarCalendarios();
	}
	
	public static String getHash(String str) throws NoSuchAlgorithmException {
		String hash = "";
		MessageDigest md = MessageDigest.getInstance("SHA1");
		
        md.reset();
        
        byte[] buffer = str.getBytes();
        
        md.update(buffer);
        
        byte[] digest = md.digest();

        for (int i = 0; i < digest.length; i++) {
        	hash +=  Integer.toString((digest[i] & 0xff) + 0x100, 16).substring(1);
        }
        
        return hash;
	}
	
	public static Date getFechaActual() {
		Calendar calendar = Calendar.getInstance();
		
		return calendar.getTime();
	}
	
	public static Integer getAnioActual() {
		Calendar calendar = Calendar.getInstance();
		
		return calendar.get(Calendar.YEAR);
	}
	
	public static Integer getAnio(Date date) {
		Calendar calendar = Calendar.getInstance();
		
		calendar.setTime(date);
		
		return calendar.get(Calendar.YEAR);
	}
	
	public static Integer getMesActual() {
		Calendar calendar = Calendar.getInstance();
		
		return calendar.get(Calendar.MONTH) + 1;
	}
	
	public static Integer getMes(Date date) {
		Calendar calendar = Calendar.getInstance();
		
		calendar.setTime(date);
		
		return calendar.get(Calendar.MONTH) + 1;
	}
	
	public static Integer getDia(Date date) {
		Calendar calendar = Calendar.getInstance();
		
		calendar.setTime(date);
		
		return calendar.get(Calendar.DATE);
	}
	
	public static Integer getHoraActual() {
		Calendar calendar = Calendar.getInstance();
		
		return calendar.get(Calendar.HOUR_OF_DAY);
	}
	
	public static void displayFeedbackMessage(JComponent component, String feedbackMessage) {
		JOptionPane.showMessageDialog(component.getParent(),
			    feedbackMessage,
			    "Info",
			    JOptionPane.INFORMATION_MESSAGE);
	}
	
	public static void displayErrorMessage(JComponent component, String errorMessage) {
		JOptionPane.showMessageDialog(component.getParent(),
			    errorMessage,
			    "Error",
			    JOptionPane.ERROR_MESSAGE);
	}
	
	private static void generarUsuarios() {		
		try {
			IServicioUsuarios servicioUsuarios = new ServicioUsuarios();
			
			String usuario1 = "empleado1";
			String nombre1 = "Empleado 1";
			String password1 = "123456";
			
			if(!servicioUsuarios.existeUsuario(usuario1)) {
				servicioUsuarios.crearUsuario(usuario1, nombre1, password1);
			}
			
			String usuario2 = "empleado2";
			String nombre2 = "Empleado 2";
			String password2 = "123456";
			
			if(!servicioUsuarios.existeUsuario(usuario2)) {
				servicioUsuarios.crearUsuario(usuario2, nombre2, password2);
			}
			
		} catch (ServiceException e) {
			System.out.println(e.getMessage());
		}
	}
	
	private static void generarTiposPago() {
		IRepository<TipoPago> repositorioTiposPago = new Repository<TipoPago>();
		
		if(!existeTipoPago("Efectivo")) {
			TipoPago efectivo = new TipoPago();	
			
			efectivo.setDescripcion("Efectivo");
			
			try {
				repositorioTiposPago.saveOrUpdate(efectivo);
			} catch (RepositoryException e) {
				System.out.println(e.getMessage());
			}
		}
		
		if(!existeTipoPago("Debito")) {
			TipoPago debito = new TipoPago();	
			
			debito.setDescripcion("Debito");
			
			try {
				repositorioTiposPago.saveOrUpdate(debito);
			} catch (RepositoryException e) {
				System.out.println(e.getMessage());
			}
		}
	}
	
	private static void generarCanchas() {		
		IServicioCanchas servicioCanchas = new ServicioCanchas();
		
		try {
			if(servicioCanchas.getCancha(1) == null) {
				servicioCanchas.registrarCancha("Cancha 1", true);
			}
		
			if(servicioCanchas.getCancha(2) == null) {
				servicioCanchas.registrarCancha("Cancha 2", false);
			}
			
			if(servicioCanchas.getCancha(3) == null) {
				servicioCanchas.registrarCancha("Cancha 3", false);
			}	
		} catch (ServiceException e) {
			System.out.println(e.getMessage());
		}
	}
	
	private static Boolean existeTipoPago(String descripcion) {
		IRepository<TipoPago> repositorioTiposPago = new Repository<TipoPago>();
		String queryExpression = "from TipoPago t where t.descripcion = :descripcion";
		QueryParameter parameter = new QueryParameter("descripcion", descripcion);
		TipoPago tipoPago = null;
		
		try {
			tipoPago = repositorioTiposPago.get(queryExpression, parameter);
		} catch (RepositoryException e) {
			System.out.println(e.getMessage());
		}
		
		return tipoPago != null;
	}
	
	private static void generarCalendarios() {
		IServicioClientes servicioClientes = new ServicioClientes();
		IServicioCanchas servicioCanchas = new ServicioCanchas();
		IServicioClases servicioClases = new ServicioClases(servicioClientes);
		IServicioReservas servicioReservas = new ServicioReservas(servicioClientes, servicioCanchas);
		
		try {
			Boolean sobreescribirCalendarioExistente = true;
			
			servicioClases.generarCalendarioClases(sobreescribirCalendarioExistente);
			servicioReservas.generarCalendarioReservasMensual(sobreescribirCalendarioExistente);
		} catch (ServiceException e) {
			System.out.println(e.getMessage());
		}
	}
}
